// 深克隆：只要有下一级，就克隆一下
function deepClone(obj, cache = new Set()) {
    if (obj instanceof RegExp) return new RegExp(obj);
    if (obj instanceof Date) return new Date(obj);
    if (obj instanceof Error) return new Error(obj.message);// Error 类型要返回obj.message
    if (typeof obj === 'bigint' || typeof obj === 'symbol') return Object(obj)
    if (typeof obj === 'function') {
        // 函数要返回新函数
        return function () {
            obj.call(this, ...arguments)
        }
    }

    if (obj === null || typeof obj !== 'object' || cache.has(obj)) {
        return obj
    }

    // 解决循环引用的问题
    cache.add(obj)
    
    let keys = [
        ...Object.keys(obj),// 不包含symbol的
        ...Object.getOwnPropertySymbols(obj)
    ],// Reflect.ownKeys 也可以
        result = new obj.constructor();

    keys.forEach(key => {
        if (obj.hasOwnProperty(key)) {
            result[key] = deepClone(obj[key], cache)
        }
    })

    return result
}